/*
 * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd.
 *
 * Author:     jouyouyun <jouyouwen717@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package main

import (
	C "gopkg.in/check.v1"
	"pkg.deepin.io/lib/utils"
	"testing"
)

func Test(t *testing.T) { C.TestingT(t) }

var _ = C.Suite(&Graphic{})

const (
	originImg               = "testdata/origin_1920x1080.jpg"
	originImgWidth          = 1920
	originImgHeight         = 1080
	originImgDominantColorH = 198.6
	originImgDominantColorS = 0.40
	originImgDominantColorV = 0.43

	originImgPngSmall       = "testdata/origin_small_200x200.png"
	originImgPngSmallWidth  = 200
	originImgPngSmallHeight = 200
	originImgPngIcon1       = "testdata/origin_icon_1_48x48.png"
	originImgPngIcon2       = "testdata/origin_icon_2_48x48.png"
	originIconWidth         = 48
	originIconHeight        = 48
)

// data uri for originImgPngIcon2
const testDataUri = ``

func delta(x, y float64) float64 {
	if x >= y {
		return x - y
	}
	return y - x
}

func sumFileMd5(f string) (md5 string) {
	md5, _ = utils.SumFileMd5(f)
	return
}

func (g *Graphic) TestBlurImage(c *C.C) {
	resultFile := "testdata/test_blurimage.png"
	err := g.BlurImage(originImg, resultFile, 50, 1, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "1b6781963a66148aed343325d08cfec0")
}

func (g *Graphic) TestClipImage(c *C.C) {
	resultFile := "testdata/test_clipimage_100x200.png"
	err := g.ClipImage(originImg, resultFile, 0, 0, 100, 200, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "fa2b58bdc0aa09ae837e23828eda0445")
}

func (g *Graphic) TestConvertImage(c *C.C) {
	resultFile := "testdata/test_convertimage.png"
	err := g.ConvertImage(originImg, resultFile, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "d389abd6706e918a8061d33cd53f8a27")
}

func (g *Graphic) TestConvertImageToDataUri(c *C.C) {
	dataUri, err := g.ConvertImageToDataUri(originImgPngIcon2)
	if err != nil {
		c.Error(err)
	}
	c.Check(dataUri, C.Equals, testDataUri)
}

func (g *Graphic) TestConvertDataUriToImage(c *C.C) {
	resultFile := "testdata/test_convertdatauri.png"
	err := g.ConvertDataUriToImage(testDataUri, resultFile, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "adaef9427c10ba58e4e94aaee27c5486")
}

func (g *Graphic) TestCompositeImage(c *C.C) {
	resultFile := "testdata/test_compositeimage.png"
	err := g.CompositeImage(originImgPngSmall, originImgPngIcon1, resultFile, 0, 0, "png")
	if err != nil {
		c.Error(err)
	}
	err = g.CompositeImage(resultFile, originImgPngIcon2, resultFile, 24, 24, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "4209e6810ca64189048b25b3aac4b9da")
}

func (g *Graphic) TestCompositeImageUri(c *C.C) {
	resultFile := "testdata/test_compositeimageuri.png"
	srcImageUri, _ := g.ConvertImageToDataUri(originImgPngSmall)
	compImageUri1, _ := g.ConvertImageToDataUri(originImgPngIcon1)
	compImageUri2, _ := g.ConvertImageToDataUri(originImgPngIcon2)
	resultDataUri, _ := g.CompositeImageUri(srcImageUri, compImageUri1, 0, 0, "png")
	resultDataUri, _ = g.CompositeImageUri(resultDataUri, compImageUri2, 24, 24, "png")
	err := g.ConvertDataUriToImage(resultDataUri, resultFile, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "4209e6810ca64189048b25b3aac4b9da")
}

func (g *Graphic) TestGetDominantColorOfImage(c *C.C) {
	h, s, v, err := g.GetDominantColorOfImage(originImg)
	if err != nil {
		c.Error(err)
	}
	if delta(h, originImgDominantColorH) > 1 ||
		delta(s, originImgDominantColorS) > 0.1 ||
		delta(v, originImgDominantColorV) > 0.1 {
		c.Error("h, s, v = ", h, s, v)
	}
}

func (g *Graphic) TestFillImage(c *C.C) {
	resultFile := "testdata/test_flllimage_tile_200x200.png"
	err := g.FillImage(originImg, resultFile, 200, 200, "tile", "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "3f12c9173e7d41bc697ca0a2ae56d7e0")

	resultFile = "testdata/test_flllimage_tile_1600x1000.png"
	err = g.FillImage(originImg, resultFile, 1600, 1000, "tile", "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "bc2ce31bc1bfa42737557a76510b8d68")

	resultFile = "testdata/test_flllimage_center_400x400.png"
	err = g.FillImage(originImg, resultFile, 400, 400, "center", "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "3dda8c7af16b6580e448f32594e23ddd")

	resultFile = "testdata/test_flllimage_center_1600x1000.png"
	err = g.FillImage(originImg, resultFile, 1600, 1000, "center", "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "e0f0d511b2988aa24b9b2f5d29ef12b0")
}

func (g *Graphic) TestFlipImageHorizontal(c *C.C) {
	resultFile := "testdata/test_flipimagehorizontal.png"
	err := g.FlipImageHorizontal(originImg, resultFile, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "5447f8349de7c114f8a7f2b11aef481e")
}

func (g *Graphic) TestFlipImageVertical(c *C.C) {
	resultFile := "testdata/test_flipimagevertical.png"
	err := g.FlipImageVertical(originImg, resultFile, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "914262cef701016c67f3260df994f0ae")
}

func (g *Graphic) TestHsv(c *C.C) {
	for r := 0; r < 255; r += 7 {
		for gg := 0; gg < 255; gg += 5 {
			for b := 0; b < 255; b += 3 {
				r0, g0, b0 := uint8(r), uint8(gg), uint8(b)
				h, s, v := g.Rgb2Hsv(r0, g0, b0)
				r1, g1, b1 := g.Hsv2Rgb(h, s, v)
				if delta(float64(r0), float64(r1)) > 1 || delta(float64(g0), float64(g1)) > 1 || delta(float64(b0), float64(b1)) > 1 {
					c.Fatalf("r0, g0, b0 = %d, %d, %d   r1, g1, b1 = %d, %d, %d", r0, g0, b0, r1, g1, b1)
				}
			}
		}
	}
}

func (g *Graphic) TestGetImageSize(c *C.C) {
	w, h, err := g.GetImageSize(originImg)
	if err != nil {
		c.Error(err)
	}
	c.Check(int(w), C.Equals, originImgWidth)
	c.Check(int(h), C.Equals, originImgHeight)
}

func (g *Graphic) TestResizeImage(c *C.C) {
	resultFile := "testdata/test_scaleimage_500x600.png"
	err := g.ResizeImage(originImg, resultFile, 500, 600, "png")
	if err != nil {
		c.Error(err)
	}
	w, h, err := g.GetImageSize(resultFile)
	if err != nil {
		c.Error(err)
	}
	c.Check(int(w), C.Equals, 500)
	c.Check(int(h), C.Equals, 600)
	c.Check(sumFileMd5(resultFile), C.Equals, "66a43cf723d520e107cfa0284a605ebf")
}

func (g *Graphic) TestThumbnailImage(c *C.C) {
	resultFile := "testdata/test_thumbnail.png"
	maxWidth, maxHeight := 200, 200
	err := g.ThumbnailImage(originImg, resultFile, uint32(maxWidth), uint32(maxHeight), "png")
	if err != nil {
		c.Error(err)
	}
	w, h, _ := g.GetImageSize(resultFile)
	c.Check(int(w) <= maxWidth, C.Equals, true)
	c.Check(int(h) <= maxHeight, C.Equals, true)
	c.Check(sumFileMd5(resultFile), C.Equals, "8852517df5cc9c1fbf12f110084574a9")
}

func (g *Graphic) TestRotateImageLeft(c *C.C) {
	resultFile := "testdata/test_rotateimageleft.png"
	err := g.RotateImageLeft(originImg, resultFile, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "e28427752e8b1fa7a298909f04c3d1a8")
}

func (g *Graphic) TestRotateImageRight(c *C.C) {
	resultFile := "testdata/test_rotateimageright.png"
	err := g.RotateImageRight(originImg, resultFile, "png")
	if err != nil {
		c.Error(err)
	}
	c.Check(sumFileMd5(resultFile), C.Equals, "e9142938dda0537c7e1bf9eb0a0345f6")
}
